//
//  CActiveAnimation.cpp
//  Monster_Martial_Arts_Version_0
//
//  Created by chiawei.tseng on 13/1/7.
//
//

#include "cocos2d.h"
#include "CActiveAnimation.h"
#include "CAnimationSystem.h"
#include "CArmature.h"

using namespace cocos2d;

CAnimationEvent::CAnimationEvent()
{
    m_AnimationInstance = NULL;
}

CAnimationEvent::~CAnimationEvent()
{
}

void CAnimationEvent::Init(CAnimationSystem* ptr , ANIMATION_ID animationID)
{
    m_AnimationInstance = ptr;
    
    m_AniamtionID = animationID;
}

void CAnimationEvent::RunAction()

{
    const char* AnimationName = GetAnimationMapping(m_AniamtionID);
    
    CCAssert(AnimationName,"the AnimationName is NULL");
    
    m_AnimationInstance->PlayeToMyMasterAnimation(AnimationName);
}


const char* CAnimationEvent::GetAnimationMapping(ANIMATION_ID animationID)
{
    switch(animationID)
    {
        case ANIMATION_ID_STAND:
            return "stand";
        case ANIMATION_ID_RUN:
            return "run";
        case ANIMATION_ID_ATTACK:
            return "attack";
        case ANIMATION_ID_HEAL:
            return "attack_frame2";
        default:
            return NULL;
    }
    
    return NULL;
}


//=================================================================


CAniamtionEventCallBack::CAniamtionEventCallBack()
{
    m_ClassPtr = NULL;
}

CAniamtionEventCallBack::~CAniamtionEventCallBack()
{
    m_ClassPtr = NULL;
}

void CAniamtionEventCallBack::Init(CActiveAnimation* ClassPtr)
{
    CCAssert(ClassPtr,"ClassPtr is NULL");
    
    m_ClassPtr = ClassPtr;
}

void CAniamtionEventCallBack::animationHandler(const char* _aniType, const char* _aniID, const char* _frameID)
{

    if (strcmp(_aniType, START)==0)
    {
        m_ClassPtr->StartAniamtionCallBack();
    }
    else if(strcmp(_aniType, COMPLETE)==0)
    {
        m_ClassPtr->CompleteAnaimationCallBack();
    }
    else if(strcmp(_aniType,LOOP_COMPLETE)==0)
    {
        m_ClassPtr->LoopCompleteAnimationCallBack();
    }
        
}


//=================================================================

CActiveAnimation::CActiveAnimation()
{
    m_nCurrAnimationIndex = INVALID_INDEX;
    m_nNextAnimationIndex = INVALID_INDEX;
    
    m_AnimationSys = NULL;
    
    m_AnimationCallBack = NULL;
}

CActiveAnimation::~CActiveAnimation()
{
    if (m_AnimationCallBack)
    {
        delete m_AnimationCallBack;
    
        m_AnimationCallBack = NULL;
    }
}

void CActiveAnimation::Init(CAnimationSystem* m_Sys,AnimationData Data)
{
    m_AnimationData = Data;
    
    m_AnimationCallBack = new CAniamtionEventCallBack();
    
    m_AnimationCallBack->Init(this);
    
    m_AnimationSys = m_Sys;
    
    CreateAnimationContext();
}

void CActiveAnimation::EnteringAnimation()
{
    m_nCurrAnimationIndex = INVALID_INDEX;
    
    m_nNextAnimationIndex = START_INDEX;
    
    m_AnimationSys->RegisterAniEventListener(m_AnimationCallBack);
}

void CActiveAnimation::RunAnimation(float dt)
{
    
    m_AnimationSys->UpdateMyMasterAnimation(dt);
    
    if (m_nCurrAnimationIndex != m_nNextAnimationIndex)
    {
        m_nCurrAnimationIndex = m_nNextAnimationIndex;
        
        if(m_nCurrAnimationIndex<m_AnimationEvents.size())
        {
            m_AnimationEvents[m_nCurrAnimationIndex]->RunAction();
        }
        else
        {
            m_AnimationSys->ChangeActiveAnimation(m_AnimationData.m_nNextActiveAnimationID);
        }
            
    }
    
}

void CActiveAnimation::LeavingAnimation()
{
    
    m_nCurrAnimationIndex = INVALID_INDEX;
    m_nNextAnimationIndex = INVALID_INDEX;
}

void CActiveAnimation::CreateAnimationContext()
{
    for (int i= 0 ; i<ANIMATION_EVENT_MAX; i++)
    {
        if (m_AnimationData.m_AniamtionIDs[i] != INVALID_ANIMATION_ID)
        {
            CAnimationEvent* tmp = new CAnimationEvent();
            
            tmp->Init(m_AnimationSys,m_AnimationData.m_AniamtionIDs[i]);
            
            m_AnimationEvents.push_back(tmp);
        }
    }
}

bool CActiveAnimation::isCanChangeActiveAnimation()
{
    
    return m_AnimationData.m_RunLoop || m_nCurrAnimationIndex == m_AnimationData.m_AnimationCount;
}

void CActiveAnimation::Release()
{
    vector<CAnimationEvent*>::iterator pi = m_AnimationEvents.begin();
    
    while (pi != m_AnimationEvents.end())
    {
        delete (*pi);
        (*pi) = NULL;
        
        pi = m_AnimationEvents.erase(pi);
        
    }
}

void CActiveAnimation::StartAniamtionCallBack()
{
    onProcessCallBack(CALLBACK_EVENT_START);
}

void CActiveAnimation::CompleteAnaimationCallBack()
{
    CCAssert(!m_AnimationData.m_RunLoop,"the ActiveAnimation is Entering this callBack but ActiveAnaimtion is 'runLoop' ");
    
    if(m_nNextAnimationIndex < m_AnimationData.m_AnimationCount)
    {
        m_nNextAnimationIndex++;
    }
    
    onProcessCallBack(CALLBACK_EVENT_COMPLETE);
    
    /*if (m_nCurrAnimationIndex >= m_AnimationData.m_AnimationCount)
    {
        m_AnimationSys->ChangeActiveAnimation(m_AnimationData.m_nNextActiveAnimationID);
    }*/
}

void CActiveAnimation::LoopCompleteAnimationCallBack()
{
    onProcessCallBack(CALLBACK_EVENT_LOOP_COMPLETE);
}

void CActiveAnimation::RegisterCallBack(CCallBack* Ptr)
{
    CCAssert(Ptr, "call Back Function not NULL");
    
    m_CallBackClassSet.push_back(Ptr);
}


void CActiveAnimation::onProcessCallBack(CALLBACK_EVENT callBackEvent)
{
    list<CCallBack*>::iterator pi = m_CallBackClassSet.begin();
    
    while (pi != m_CallBackClassSet.end())
    {
        ACTION_EVENT tmp;
        
        tmp.callBackEvent = static_cast<int>(callBackEvent);
        
        (*pi)->invoke((void*)&tmp);
        
        pi++;
    }
}






















